package com.zhuss.order.processor;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.zhuss.WxCertParam;
import com.zhuss.bean.bo.order.order.WxPayBo;
import com.zhuss.bean.vo.order.order.WxPayVo;
import com.zhuss.common.AbstractProcessor;
import com.zhuss.common.Processor;
import com.zhuss.enums.IsEnum;
import com.zhuss.exception.DzcxException;
import com.zhuss.exception.ExceptionCode;

/**
 * 微信支付 processor
 * @Author: zhushanshuo
 * @Date: 2021/02/07 22:11
 */
@Component("wxPayProcessor")
public class WxPayProcessor extends AbstractProcessor<WxPayVo, WxPayBo> implements Processor<WxPayVo, WxPayBo> {

	@Value("${wxpay.appId}")
    private String appId;
	
	@Value("${wxpay.mchId}")
    private String mchId;
	
	@Value("${wxpay.key}")
    private String key;
	
	@Value("${wxpay.tradeType}")
	private String tradeType;
	
	@Value("${wxpay.notifyUrl}")
	private String notifyUrl;
	
    
    /**
     * 校验
     */
    @Override
    public void check(WxPayBo bo) throws DzcxException {
    }
    
    /**
     * 操作方法
     * @throws Exception 
     */
    @Override
    public WxPayVo process(WxPayBo param) throws DzcxException {
    	
    	WxPayVo result = new WxPayVo();
    	
    	param.buildAppId(appId).buildMchId(mchId).buildKey(key).buildTradeType(tradeType).buildNotifyUrl(notifyUrl);
    	
        WxCertParam wxCertParam = new WxCertParam(param.getAppId(), param.getMchId(), param.getKey(), IsEnum.否.key(), null);
        WXPay wxPay = new WXPay(wxCertParam);

        //根据微信支付api来设置
        Map<String,String> data = new HashMap<>();
        data.put("appid",param.getAppId());
        data.put("mch_id",param.getMchId());         //商户号
        data.put("trade_type", param.getTradeType());                         //支付场景 APP 微信app支付 JSAPI 公众号支付  NATIVE 扫码支付
        data.put("notify_url", param.getNotifyUrl());                     //回调地址
        data.put("spbill_create_ip", param.getSpbillCreateIp());             //终端ip
        data.put("total_fee", param.getTotalPrice() + "");       //订单总金额
        data.put("fee_type", param.getFeeType());                           //默认人民币
        data.put("out_trade_no", param.getOrderNo());   //交易号
        data.put("body", param.getBody());
        data.put("nonce_str", param.getNonceStr());   // 随机字符串小于32位
        String sign = null;
        
		try {
			sign = WXPayUtil.generateSignature(data, wxCertParam.getKey());
		} catch (Exception e) {
			e.printStackTrace();
			throw new DzcxException(ExceptionCode.微信支付获取签名错误);
		}  
		
		//签名
        data.put("sign",sign);

        /** wxPay.unifiedOrder 这个方法中调用微信统一下单接口 */
        Map<String, String> respData = null;
		try {
			respData = wxPay.unifiedOrder(data);
		} catch (Exception e) {
			e.printStackTrace();
			throw new DzcxException(ExceptionCode.微信支付下单错误);
		}
        if (respData.get("return_code").equals("SUCCESS")){

            //返回给APP端的参数，APP端再调起支付接口
            Map<String,String> repData = new HashMap<>();
            repData.put("appid", param.getAppId());
            repData.put("partnerid", param.getMchId());
            repData.put("prepayid", respData.get("prepay_id"));
            repData.put("package", "Sign=WXPay");
            repData.put("noncestr", respData.get("nonce_str"));
            Date date = new Date();
            repData.put("timestamp",String.valueOf(date.getTime() / 1000));
            String sign2 = null;
			try {
				sign2 = WXPayUtil.generateSignature(repData, wxCertParam.getKey());
			} catch (Exception e) {
				e.printStackTrace();
				throw new DzcxException(ExceptionCode.微信支付获取签名错误);
			} //签名
            respData.put("sign",sign2);
            respData.put("timestamp",repData.get("timestamp"));
            respData.put("package","WXPay");
            BeanUtils.copyProperties(param, result);
            result.setNonceStr(respData.get("nonce_str"));
            result.setPrepayId(respData.get("prepay_id"));
            result.setWxPackage("Sign=WXPay");
            result.setReturnMsg(respData.get("return_msg"));
            result.setResultCode(respData.get("result_code"));
            result.setReturnCode(respData.get("return_code"));
            result.setTime(date);
            
            result.setSign(sign2);
            
            return result;
        }
        return result;
    }
    
    /**
     * 操作日志
     */
	@Override
	public WxPayVo log(WxPayBo param) throws DzcxException {
    	return null;
	}
}
